package thread;

/**
 * 当一个静态方法上使用synchronized修饰后，该方法一定是同步的。
 */
public class SyncDemo3 {
    public static void main(String[] args) {
        Boo b1 = new Boo();
        Boo b2 = new Boo();
        Thread t1 = new Thread(){
            public void run(){
                b1.dosome();
            }
        };
        Thread t2 = new Thread(){
            public void run(){
                b2.dosome();
            }
        };
        t1.start();
        t2.start();
    }
}
class Boo{
    /*
        使用上面main方法中的方式测试，两个线程一个调用b1实例的dosome方法，另一个线程
        调用b2实例的dosome方法:
        如果dosome方法是一个成员方法，那么synchronized指定的同步监视器对象为this，
        由于两个线程调用的并非同一个对象的dosome方法，因此看到的this也不是同一个对象
        所以他们是可以同时执行的。

        如果dosome方法是一个静态方法，那么synchronized指定的同步监视器为当前类的
        类对象(Class实例)，由于每个类都有且只有一个类对象与之对应，因此多个线程看到的
        同一个类一定也是同一个类对象，因此执行dosome方法时是分开的。

        类对象:Class实例，在JVM内部每个被加载的类都有且只有一个Class实例与之绑定，
        后面学习反射知识时会详细介绍这个对象。
     */
//    public synchronized void dosome(){
//    在静态方法上直接使用synchronized时，锁对象不可选，只能是当前类的类对象
//    public synchronized static void dosome(){

    public static void dosome(){
        //在静态方法中如果使用同步块，同步监视器对象通常也使用当前类的类对象.
        //获取类对象的方式:类名.class
        synchronized (Boo.class) {
            try {
                Thread t = Thread.currentThread();
                System.out.println(t.getName() + ":正在执行dosome方法...");
                Thread.sleep(5000);
                System.out.println(t.getName() + ":执行dosome方法完毕!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}